#include "drv_sht20.h"
#include "drv_iic.h"// 依赖I2C驱动
#include "drv_systick.h"  // 依赖延时函数
#include "stdio.h"


/**
 * @brief  初始化SHT20传感器
 * @note   实际是初始化I2C总线（因为SHT20通过I2C通信）
 */
float tem=0;
float hum=0;
void drv_sht20_init(void)
{
	drv_iic_init(); // 调用I2C初始化函数，配置SCL/SDA引脚

}

/**
 * @brief  从SHT20读取温度原始数据（16位）
 * @retval 成功：返回16位温度原始值；失败：返回NOACK（非应答）
 * @note   通信流程：发送起始信号→发送设备地址→发送温度测量指令→
 *         重新起始→读取数据→发送停止信号
 */
uint16_t drv_sht20_read(void)
{
	uint8_t data[2];// 存储读取到的2字节原始数据
	uint16_t ret=0;// 用于拼接原始数据
	drv_iic_start();// 发送I2C起始信号（开始通信）
	drv_iic_senddata(0x80); // 发送SHT20写地址（0x80 = 0x40 << 1，7位地址0x40，最低位0表示写）
	if(drv_iic_waitACK()!=ACK) // 等待传感器应答
	{
		drv_iic_stop();// 发送停止信号，终止通信
		return NoACK;// 返回失败标志
	}

	  // 发送温度测量指令（0xE3：触发温度测量，hold master模式）
    // hold master模式：传感器会拉低SCL线，直到测量完成
	drv_iic_senddata(0xe3);//获取温度
	if(drv_iic_waitACK()!=ACK)// 等待传感器应答
	{
		drv_iic_stop();
		return NoACK;
	}

	drv_iic_start(); // 发送重复起始信号（切换到读操作）
	drv_iic_senddata(0x81); // 发送SHT20读地址（0x81 = 0x40 << 1 | 1，最低位1表示读）
	if(drv_iic_waitACK()!=ACK)// 等待传感器应答
	{
		drv_iic_stop();
		return NoACK;
	}
	// 等待测量完成（SHT20温度测量最大耗时约85ms）
    // 注：hold master模式下可省略此延时，传感器会通过SCL线阻塞等待
	delay_ms(85);
	data[0]=drv_iic_receivedata(ACK);// 接收高8位     读取第一个字节（温度高8位），并发送ACK表示继续读取
	data[1]=drv_iic_receivedata(NoACK);// 接收低8位      读取第二个字节（温度低8位），发送NOACK表示读取结束
	drv_iic_stop();// 发送停止信号，结束通信
	//printf("data[0]=%d data[2]=%d\r\n",data[0],data[1]);// 打印原始数据（用于调试）
	ret=((data[0]<<8)|data[1]);// 拼接2字节数据（原始温度值为16位）
	return ret;
}

/**
 * @brief  软复位SHT20传感器
 * @retval 0：复位成功；NOACK：复位失败
 * @note   复位后传感器恢复默认状态，需等待约15ms稳定时间
 */
uint8_t drv_sht20_reset(void)
{
	drv_iic_start();// 发送起始信号
	drv_iic_senddata(0x80); // 发送写地址
	if(drv_iic_waitACK()!=ACK)
	{
		drv_iic_stop();
		return NoACK;
	}

	drv_iic_senddata(0xfe);  // 发送软复位指令（0xFE：SHT20复位命令）
	if(drv_iic_waitACK()!=ACK)
	{
		drv_iic_stop();
		return NoACK;
	}
	drv_iic_stop();// 发送停止信号
	return 0;// 复位成功
}

/**
 * @brief  解析温度数据并打印
 * @note   将原始16位数据转换为实际温度值（℃），公式来自SHT20数据手册
 */
float drv_sht20_getdata(void)
{
	uint16_t temp=0;// 存储原始温度数据
	temp=drv_sht20_read(); // 读取原始数据
	
	// 温度转换公式：T(℃) = -46.85 + 175.72 * (raw_temp / 65536)
    // 其中raw_temp是16位原始数据（需忽略低2位状态位
	tem=-46.85+175.72*((float)temp/65536);
	printf("Temperature:%.2f\r\n",tem);
	return tem;
}


uint16_t drv_sht20_read_hum(void)
{
	uint8_t data[2];// 存储读取到的2字节原始数据
	uint16_t ret=0;// 用于拼接原始数据
	drv_iic_start();// 发送I2C起始信号（开始通信）
	drv_iic_senddata(0x80); // 发送SHT20写地址（0x80 = 0x40 << 1，7位地址0x40，最低位0表示写）
	if(drv_iic_waitACK()!=ACK) // 等待传感器应答
	{
		drv_iic_stop();// 发送停止信号，终止通信
		return NoACK;// 返回失败标志
	}

	  // 发送湿度测量指令（0xE3：触发湿度测量，hold master模式）
    // hold master模式：传感器会拉低SCL线，直到测量完成
	drv_iic_senddata(0xe5);//获取湿度
	if(drv_iic_waitACK()!=ACK)// 等待传感器应答
	{
		drv_iic_stop();
		return NoACK;
	}

	drv_iic_start(); // 发送重复起始信号（切换到读操作）
	drv_iic_senddata(0x81); // 发送SHT20读地址（0x81 = 0x40 << 1 | 1，最低位1表示读）
	if(drv_iic_waitACK()!=ACK)// 等待传感器应答
	{
		drv_iic_stop();
		return NoACK;
	}
	// 等待测量完成（SHT20湿度测量最大耗时约85ms）
    // 注：hold master模式下可省略此延时，传感器会通过SCL线阻塞等待
	delay_ms(29);
	data[0]=drv_iic_receivedata(ACK);// 接收高8位     读取第一个字节（温度高8位），并发送ACK表示继续读取
	data[1]=drv_iic_receivedata(NoACK);// 接收低8位      读取第二个字节（温度低8位），发送NOACK表示读取结束
	drv_iic_stop();// 发送停止信号，结束通信
	//printf("data[0]=%d data[1]=%d\r\n",data[0],data[1]);// 打印原始数据（用于调试）
	ret=((data[0]<<8)|data[1]);// 拼接2字节数据（原始温度值为16位）
	return ret;
}


/**
 * @brief  解析温度数据并打印
 * @note   将原始16位数据转换为实际温度值（℃），公式来自SHT20数据手册
 */
float drv_sht20_gethumdata(void)
{
	uint16_t temp=0;// 存储原始温度数据
	temp=drv_sht20_read_hum(); // 读取原始数据
	
	// 温度转换公式：T(℃) = -6 + 125 * (temp / 65536)
    // 其中raw_temp是16位原始数据（需忽略低2位状态位
	hum= -6 + 125*((float)temp/65536);
	printf("humidity:%.2f\r\n",hum);
	return hum;
}

